import logging
import os.path

import static
from common.utils.db_util import DBUtil
from common.utils.mongo_util import MongoDBUtil
from common.utils.read_file import read_yaml
from common.utils.redis_util import RedisUtil

logger = logging.getLogger(__name__)


class DBInfo:
    def __init__(self, dbtype, dbname, sqls):
        self.dbtype = dbtype
        self.dbname = dbname
        self.sqls = sqls

    def get_dbinfo(self):
        return self.__dict__

    def sss(self, tables, dbinfo):
        self.releation = [tables, dbinfo]


class BasePredata:
    @classmethod
    def process(cls, interface, predata_path=None):
        if not predata_path:
            predata_path = os.path.join(static.DATA_PATH, 'userinterface', 'predata.yaml')
        config = read_yaml(predata_path)
        # 获取当前接口的配置信息
        try:
            predata = config['predata'][interface]
        except KeyError:
            raise Exception(f'缺少配置接口:{interface}的前置处理')
        for k, v in predata.items():
            # 数据库前置处理
            if k == 'db_predata':
                DBPreData.process(v)
            # mongodb前置处理
            elif k == 'mongo_predata':
                MongoPreData.process(v)
            elif k == 'redis_predata':
                RedisPreData.process(v)
            # 其他前置处理，如消息队列、文件处理等
            else:
                pass


class DBPreData:
    def __init__(self, dbtype, dbname, insert, update, delete):
        self.dbtype = dbtype
        self.dbname = dbname
        self.insert = insert
        self.update = update
        self.delete = delete

    @classmethod
    def process(cls, predata):
        predata_list = [
            DBPreData(data['dbtype'], data['dbname'], data.get('insert'), data.get('update'), data.get('delete')) for
            data in predata]
        for predata in predata_list:
            predata.process_data()

    def process_data(self):
        # if self.insert:
        #     logger.info(f'数据库前置插入数据:{self.insert}')
        #     insert_result = DBUtil(self.dbtype, self.dbname).execute_insert(self.insert)
        #     logger.info(f'数据库前置插入数据完成')
        if self.update:
            logger.info(f'数据库前置更新数据:{self.update}')
            update_result = DBUtil(self.dbtype, self.dbname).execute_update(self.update)
            logger.info(f'数据库前置更新数据完成')
        if self.delete:
            logger.info(f'数据库前置删除数据:{self.delete}')
            delete_result = DBUtil(self.dbtype, self.dbname).execute_delete(self.delete)
            logger.info(f'数据库前置删除数据完成')
        result = {'update_result': update_result, 'delete_result': delete_result}
        return result


class MongoPreData:
    def __init__(self, dbname, collection, insert, update, delete):
        self.dbname = dbname
        self.collection = collection
        self.insert = insert
        self.update = update
        self.delete = delete

    @classmethod
    def process(cls, predata):
        predata_list = [MongoPreData(data['dbname'], data['collection'], data.get('insert'), data.get('update'),
                                     data.get('delete')) for data in predata]
        for predata in predata_list:
            predata.process_data()

    def process_data(self):
        if self.insert:
            logger.info(f'mongo前置插入数据:{self.insert}')
            insert_result = MongoDBUtil(self.dbname).insert_many(self.collection, self.insert)
            logger.info(f'mongo前置插入数据完成')
        if self.update:
            logger.info(f'mongo前置更新数据:{self.update}')
            update_result = []
            for update_info in self.update:
                result = MongoDBUtil(self.dbname).update_many(self.collection, update_info['query'],
                                                              update_info['data'])
                update_result.append(result)
            logger.info(f'mongo前置更新数据完成')
        if self.delete:
            logger.info(f'mongo前置删除数据:{self.delete}')
            delete_result = []
            for delete_info in self.delete:
                result = MongoDBUtil(self.dbname).delete_many(self.collection, delete_info)
                delete_result.append(result)
            logger.info(f'mongo前置删除数据完成')
        result = {'update_result': update_result, 'delete_result': delete_result}
        return result


class RedisPreData:
    def __init__(self, config, insert, update, delete):
        self.config = config
        self.insert = insert
        self.update = update
        self.delete = delete

    @classmethod
    def process(cls, predata):
        predata_list = [RedisPreData(data['config'], data.get('insert'), data.get('update'), data.get('delete')) for
                        data in predata]
        for predata in predata_list:
            predata.process_data()

    def process_data(self):
        if self.insert:
            logger.info(f'redis前置插入数据:{self.insert}')
            for insert_info in self.insert:
                if insert_info['type'] == 'str':
                    time = insert_info.get('time')
                    expire = time if time else 0
                    RedisUtil(self.config).set_str(insert_info['key'], insert_info['value'], expire)
                # 非插入字符串的情况
                else:
                    pass
            logger.info(f'redis前置插入数据完成')
        if self.update:
            logger.info(f'redis前置更新数据:{self.update}')
            update_result = []
            for update_info in self.update:
                result = MongoDBUtil(self.dbname).update_many(self.collection, update_info['query'],
                                                              update_info['data'])
                update_result.append(result)
            logger.info(f'redis前置更新数据完成')
        if self.delete:
            logger.info(f'redis前置删除数据:{self.delete}')
            delete_result = []
            for delete_info in self.delete:
                result = MongoDBUtil(self.dbname).delete_many(self.collection, delete_info)
                delete_result.append(result)
            logger.info(f'redis前置删除数据完成')
        # result = {'update_result': update_result, 'delete_result': delete_result}
        # return result
